library(tidyverse)
library(ggplot2)
library(readr)
Lekagul_traff <- read_csv("~/Documents/2021 Spring/SDS235/DC3-data/Traffic Data/Lekagul Sensor Data.csv")

Calculate duration of each trip for each vehicle

library(stringr)
#only select entrance data: cars need to enter and exit the preserve 
arrange_time <- Lekagul_traff %>%
  filter(grepl('entrance', `gate-name`))%>%
  group_by(`car-id`) %>%
  arrange(Timestamp, .by_group = TRUE) 

#some vehicles only has one entrace time - do they just stay in the park forever? 
#make sure there are no other odd nums of entrance (i only filtered out n == 1 because the only odd n. of entrance is 1)
no_exit_id <- arrange_time %>%
  group_by(`car-id`) %>%
  summarize(n=n()) %>%
  arrange(desc(n)) %>%
  filter(n == 1)
## `summarise()` ungrouping output (override with `.groups` argument)
#remove car id that only has one entrance
arrange_time_dur <- arrange_time %>%
  filter(!`car-id` %in% c(no_exit_id$`car-id`))

#now we have even n. of entrance, diff time for each two entrance data should assign with each trip for each car id 
arrange_time_dur$diff <- 
rep(difftime(arrange_time_dur$Timestamp[seq(2,nrow(arrange_time_dur), by =2)], arrange_time_dur$Timestamp[seq(1, nrow(arrange_time_dur), by=2)], units = "hours")
  ,each = 2)

#change different 
arrange_time_dur %>%
  mutate(diff_type = ifelse(diff < 1, "hrs<1", 
                            ifelse(diff < 12, "1<hrs<12", 
                                   ifelse(diff < 24, "12<hrs<24",
                                          ifelse(diff < 48, "24<hrs<48", "hrs>48"))))) %>%
  mutate(diff_type = ordered(diff_type, levels = c("hrs<1", "1<hrs<12", "12<hrs<24", "24<hrs<48", "hrs>48")))  %>%
  ggplot(aes(x=diff_type)) +
  geom_bar(fill="#339999") +
  labs(title = "Number of Visits for Different Duration of Time") +
  theme_minimal()

#maybe filter time < than some hours 

#for those vehicles that only had one entrance data, use maximum time - minimum to get the time stayed in the preserve 
one_entrance_time <- Lekagul_traff %>%
  filter(`car-id` %in% c(no_exit_id$`car-id`)) %>%
  group_by(`car-id`) %>%
  mutate(entry_time = min(Timestamp),
         exit_time = max(Timestamp)) %>%
  filter(Timestamp %in% c(exit_time, entry_time))%>%
         mutate(duration = difftime(exit_time, entry_time, units = "hours")) %>%
  arrange(desc(duration))
  
#another group of suspicious vehicles are the ones that are not Preserve Ranger Vehicles but pass by gates 
suspicious_id <- Lekagul_traff %>%
  filter(!grepl('general-gate',`gate-name`)) %>%
  filter(grepl('gate', `gate-name`)) %>%
  filter(`car-type` != '2P') 

suspicious_activity <- Lekagul_traff %>%
  filter(`car-id` %in% c(suspicious_id$`car-id`))

Visualization

require(magick)
## Loading required package: magick
## Linking to ImageMagick 6.9.11.57
## Enabled features: cairo, fontconfig, freetype, heic, lcms, pango, raw, rsvg, webp
## Disabled features: fftw, ghostscript, x11
require(htmlwidgets)
## Loading required package: htmlwidgets
library(plotly)
## 
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
library(ggrepel)
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
#img <- base64enc::dataURI(file = "Lekagul Roadways labeled v2.jpg")

#convert to raster 
map <- image_read("MapLargeLabels.jpg")
raster_map <- as.raster(map)

#factories 
#Roadrunner Fitness Electronics: 89,27
#Kasios Office Furniture: 90,21
#Radiance ColourTek: 109,26
#Indigo Sol Boards: 120,22

#make data frame for locations by data description and eye-ball estimation 
location <- tribble(~`gate-name`, ~x, ~y, ~`type`,
                  "Roadrunner", 89, 27, "factory",
                  "Kasios", 90, 21, "factory",
                  "Radiance", 109, 26, "factory",
                  "Indigo", 120, 22, "factory",
                  "sensor1", 62, 21, "sensor",
                  "sensor2", 66, 35, "sensor",
                  "sensor3", 76, 41, "sensor",
                  "sensor4", 88, 45, "sensor",
                  "sensor5", 103, 43, "sensor",
                  "sensor6", 102, 22, "sensor",
                  "sensor7", 89, 3, "sensor",
                  "sensor8", 74, 7, "sensor",
                  "sensor9", 119, 42, "sensor",
                  "general-gate0", 111, 190, "general-gate",
                  "general-gate1", 65, 174, "general-gate",
                  "general-gate2", 104, 166, "general-gate",
                  "general-gate3", 186, 144, "general-gate",
                  "general-gate4", 70, 102, "general-gate",
                  "general-gate5", 124, 88, "general-gate",
                  "general-gate6", 136, 63, "general-gate",
                  "general-gate7", 66, 56, "general-gate",
                  "gate0", 64, 166, "gate",
                  "gate1", 59, 155, "gate",
                  "gate2", 25, 145,"gate",
                  "gate3", 149, 139, "gate",
                  "gate4", 164, 86, "gate",
                  "gate5", 132, 54, "gate",
                  "gate6", 116, 49, "gate",
                  "gate7", 97, 40, "gate",
                  "gate8", 137, 19,"gate",
                  "ranger-base", 128, 25, "ranger-stop",
                  "ranger-stop0", 90, 183, "ranger-stop",
                  "ranger-stop1", 20, 175, "ranger-stop", 
                  "ranger-stop2", 80, 164, "ranger-stop",
                  "ranger-stop3", 147, 154,"ranger-stop",
                  "ranger-stop4", 19, 104, "ranger-stop",
                  "ranger-stop5", 151, 81, "ranger-stop",
                  "ranger-stop6", 123, 53, "ranger-stop",
                  "ranger-stop7", 101, 47, "ranger-stop",
                  "entrance0", 63, 186, "entrance",
                  "entrance1", 18, 132, "entrance",
                  "entrance2", 183, 113, "entrance",
                  "entrance3", 116, 33, "entrance",
                  "entrance4", 140, 16, "entrance",
                  "camping0", 53, 157, "camping",
                  "camping1", 129, 149, "camping",
                  "camping2", 45, 135, "camping",
                  "camping3", 46, 131,"camping",
                  "camping4", 49, 111, "camping",
                  "camping5", 21, 79, "camping",
                  "camping6", 150, 23, "camping",
                  "camping7", 181, 55,"camping",
                  "camping8", 184, 151,"camping")

plot <- ggplot(location, aes(x=x, y=y, color = type)) +
  geom_point() +
  scale_x_continuous(limits = c(0,200), breaks=seq(0,200, by = 5)) +
  scale_y_continuous(limits = c(0,200), breaks=seq(0,200, by = 5)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45)) +
  geom_label_repel(aes(label = `gate-name`), size=2) +
  scale_color_discrete(name = "type")

suspicious_location <- left_join(suspicious_activity, location, by = "gate-name") 


suspicious_location_625 <- suspicious_location %>%
   filter(`car-id` == "20150505020522-625") %>%
   mutate(time_mins = floor_date(Timestamp, unit="mins")) %>%
  mutate(time_mins = format(time_mins, "%H:%M:%S"))
 
p <- suspicious_location_625 %>%
   ggplot(aes(x=x, y=y)) +
  geom_point(aes(frame = time_mins), color = "yellow") + 
#   geom_line() + 
  scale_x_continuous(limits = c(0,200)) +
  scale_y_continuous(limits = c(0,200)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45)) +
#  geom_label_repel(aes(label = `gate-name`), size=3) + 
  labs(title = "Suspicious Movement of Unauthorized Car - 625")
## Warning: Ignoring unknown aesthetics: frame
ggplotly(p) %>%
 # add_markers(data = suspicious_location, frame = ~time_mins) %>%
    layout(images = list(
    source = raster2uri(raster_map),
          x = 0, y = 0, 
    opacity = 0.8,
      sizex = 200, sizey = 200,
      xref = "x", yref = "y", 
      xanchor = "left", yanchor = "bottom",
    sizing = "stretch",
    layer = "below"
  ))
one_time_63 <- Lekagul_traff %>%
   filter(`car-id` == "20155705025759-63") %>%
   mutate(time_hrs = floor_date(Timestamp, unit="mins"),
          time_hrs = as.character(time_hrs)) 

one_time_63 <- left_join(one_time_63, location, by = "gate-name")

p2 <- one_time_63 %>%
   ggplot(aes(x=x, y=y)) +
  geom_point(aes(frame = time_hrs), color = "pink") + 
#   geom_line() + 
  scale_x_continuous(limits = c(0,200)) +
  scale_y_continuous(limits = c(0,200)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45)) +
#  geom_label_repel(aes(label = `gate-name`), size=3) + 
  labs(title = "Suspicious Movement of Unusually Long Stay - 63")
## Warning: Ignoring unknown aesthetics: frame
#movement 
ggplotly(p2) %>%
 # add_markers(data = suspicious_location, frame = ~time_mins) %>%
    layout(images = list(
    source = raster2uri(raster_map),
          x = 0, y = 0, 
    opacity = 0.8,
      sizex = 200, sizey = 200,
      xref = "x", yref = "y", 
      xanchor = "left", yanchor = "bottom",
    sizing = "stretch",
    layer = "below"
  ))

Citations:

https://plotly-r.com/embedding-images.html

https://cran.r-project.org/web/packages/magick/vignettes/intro.html

https://plotly.com/python/images/

https://www.statology.org/filter-rows-that-contain-string-dplyr/

https://stackoverflow.com/questions/38202603/subtracting-row-2-from-row-1-repeatedly

https://www.datanovia.com/en/blog/gganimate-how-to-create-plots-with-beautiful-animation-in-r/

https://paldhous.github.io/ucb/2018/dataviz/week14.html

https://plotly-r.com/animating-views.html